

<!doctype html>

<html lang="en" data-content_root="../../../../">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>skidl.tools.spice.spice &#8212; SKiDL 1.2.2 documentation</title>
    <link rel="stylesheet" type="text/css" href="../../../../_static/pygments.css?v=fa44fd50" />
    <link rel="stylesheet" type="text/css" href="../../../../_static/bizstyle.css?v=a66e137f" />
    
    <script src="../../../../_static/documentation_options.js?v=fd7cadf9"></script>
    <script src="../../../../_static/doctools.js?v=9a2dae69"></script>
    <script src="../../../../_static/sphinx_highlight.js?v=dc90522c"></script>
    <script src="../../../../_static/bizstyle.js"></script>
    <link rel="index" title="Index" href="../../../../genindex.html" />
    <link rel="search" title="Search" href="../../../../search.html" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <!--[if lt IE 9]>
    <script src="_static/css3-mediaqueries.js"></script>
    <![endif]-->
  </head><body>
    <h1 id="site-title"><a href="../../../../../../"><img src="../../../../../../images/slim_banner.png" width="100%"></a></h1>
    
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../../../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../../../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../../../index.html">SKiDL 1.2.2 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../../../index.html" accesskey="U">Module code</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">skidl.tools.spice.spice</a></li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <h1>Source code for skidl.tools.spice.spice</h1><div class="highlight"><pre>
<span></span><span class="c1"># -*- coding: utf-8 -*-</span>

<span class="c1"># The MIT License (MIT) - Copyright (c) Dave Vandenbout.</span>

<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Handler for reading SPICE libraries.</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="p">(</span>  <span class="c1"># isort:skip</span>
    <span class="n">absolute_import</span><span class="p">,</span>
    <span class="n">division</span><span class="p">,</span>
    <span class="n">print_function</span><span class="p">,</span>
    <span class="n">unicode_literals</span><span class="p">,</span>
<span class="p">)</span>

<span class="kn">import</span> <span class="nn">os.path</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">builtins</span> <span class="kn">import</span> <span class="nb">dict</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">object</span><span class="p">,</span> <span class="nb">range</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="nb">zip</span>

<span class="k">try</span><span class="p">:</span>
    <span class="kn">from</span> <span class="nn">future</span> <span class="kn">import</span> <span class="n">standard_library</span>
    <span class="n">standard_library</span><span class="o">.</span><span class="n">install_aliases</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
    <span class="k">pass</span>

<span class="kn">from</span> <span class="nn">skidl</span> <span class="kn">import</span> <span class="n">Alias</span><span class="p">,</span> <span class="n">Net</span><span class="p">,</span> <span class="n">LIBRARY</span><span class="p">,</span> <span class="n">Part</span><span class="p">,</span> <span class="n">Pin</span>
<span class="kn">from</span> <span class="nn">skidl.logger</span> <span class="kn">import</span> <span class="n">active_logger</span>
<span class="kn">from</span> <span class="nn">skidl.utilities</span> <span class="kn">import</span> <span class="p">(</span>
    <span class="n">INDEX_SEPARATOR</span><span class="p">,</span>
    <span class="n">export_to_all</span><span class="p">,</span>
    <span class="n">find_and_open_file</span><span class="p">,</span>
    <span class="n">find_and_read_file</span><span class="p">,</span>
<span class="p">)</span>


<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;lib_suffix&quot;</span><span class="p">,</span> <span class="s2">&quot;DeviceModel&quot;</span><span class="p">,</span> <span class="s2">&quot;XspiceModel&quot;</span><span class="p">,</span> <span class="s2">&quot;Parameters&quot;</span><span class="p">]</span>


<span class="c1"># PySpice may not be installed, particularly under Python 2.</span>
<span class="k">try</span><span class="p">:</span>
    <span class="kn">from</span> <span class="nn">PySpice.Spice.Library</span> <span class="kn">import</span> <span class="n">SpiceLibrary</span>
    <span class="kn">from</span> <span class="nn">PySpice.Spice.Netlist</span> <span class="kn">import</span> <span class="p">(</span>
        <span class="n">Circuit</span> <span class="k">as</span> <span class="n">PySpiceCircuit</span><span class="p">,</span>  <span class="c1"># Avoid clash with Circuit class below.</span>
    <span class="p">)</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
    <span class="k">pass</span>

<span class="c1"># These aren&#39;t used here, but they are used in modules</span>
<span class="c1"># that include this module.</span>
<span class="n">lib_suffix</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;.lib&quot;</span><span class="p">,</span> <span class="s2">&quot;.spice&quot;</span><span class="p">]</span>


<div class="viewcode-block" id="default_lib_paths">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.default_lib_paths">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">default_lib_paths</span><span class="p">():</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Return default list of directories to search for part libraries.&quot;&quot;&quot;</span>

    <span class="c1"># Start search for part libraries in the current directory.</span>
    <span class="n">paths</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;.&quot;</span><span class="p">]</span>

    <span class="k">return</span> <span class="n">paths</span></div>



<div class="viewcode-block" id="get_fp_lib_tbl_dir">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.get_fp_lib_tbl_dir">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">get_fp_lib_tbl_dir</span><span class="p">():</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Get the path to where the global fp-lib-table file is found.&quot;&quot;&quot;</span>

    <span class="k">return</span> <span class="s2">&quot;&quot;</span> <span class="c1"># No global fp-lib-table file for SPICE.</span></div>



<span class="k">def</span> <span class="nf">_gather_statement</span><span class="p">(</span><span class="n">file</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Return list of words in a complete statement read from a SPICE file.&quot;&quot;&quot;</span>

    <span class="n">statement</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>  <span class="c1"># Holds complete SPICE statement consisting of one or more lines.</span>
    <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">file</span><span class="p">:</span>
        <span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>

        <span class="k">if</span> <span class="ow">not</span> <span class="n">line</span><span class="p">:</span>
            <span class="k">continue</span>  <span class="c1"># Ignore blank lines.</span>
        <span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;*&quot;</span><span class="p">):</span>
            <span class="k">continue</span>  <span class="c1"># Ignore comments.</span>

        <span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;+&quot;</span><span class="p">):</span>
            <span class="c1"># Continuation lines are appended to the statement.</span>
            <span class="n">statement</span> <span class="o">+=</span> <span class="s2">&quot; &quot;</span> <span class="o">+</span> <span class="n">line</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># If the current line is not a continuation, then</span>
            <span class="c1"># return the statement accumulated from the previous lines.</span>
            <span class="k">if</span> <span class="n">statement</span><span class="p">:</span>
                <span class="k">yield</span> <span class="n">statement</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>
            <span class="c1"># The current line becomes the start of the next statement.</span>
            <span class="n">statement</span> <span class="o">=</span> <span class="n">line</span><span class="p">[:]</span>

    <span class="c1"># Return any statement that was in-process when the file ended.</span>
    <span class="k">if</span> <span class="n">statement</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
        <span class="k">yield</span> <span class="n">statement</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>


<div class="viewcode-block" id="load_sch_lib">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.load_sch_lib">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">load_sch_lib</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">lib_search_paths_</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">lib_section</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Load the .subckt I/O from a SPICE library file.</span>

<span class="sd">    Args:</span>
<span class="sd">        filename: The name of the SPICE library file.</span>
<span class="sd">        lib_search_paths_ : List of directories to search for the file.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="kn">from</span> <span class="nn">skidl</span> <span class="kn">import</span> <span class="n">SPICE</span>
    <span class="kn">from</span> <span class="nn">skidl.tools</span> <span class="kn">import</span> <span class="n">lib_suffixes</span>

    <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
        <span class="c1"># A directory was given, so just use that.</span>
        <span class="n">spice_lib_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="c1"># A file name was given, so find the absolute file path in the search paths.</span>
        <span class="n">_</span><span class="p">,</span> <span class="n">spice_lib_path</span> <span class="o">=</span> <span class="n">find_and_open_file</span><span class="p">(</span>
            <span class="n">filename</span><span class="o">=</span><span class="n">filename</span><span class="p">,</span>
            <span class="n">paths</span><span class="o">=</span><span class="n">lib_search_paths_</span><span class="p">,</span>
            <span class="n">ext</span><span class="o">=</span><span class="n">lib_suffixes</span><span class="p">[</span><span class="n">SPICE</span><span class="p">],</span>
            <span class="n">exclude_binary</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
            <span class="n">descend</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span>
        <span class="p">)</span>

    <span class="c1"># Read the Spice library from the given path.</span>
    <span class="n">spice_lib</span> <span class="o">=</span> <span class="n">SpiceLibrary</span><span class="p">(</span>
        <span class="n">root_path</span><span class="o">=</span><span class="n">spice_lib_path</span><span class="p">,</span> <span class="n">recurse</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">section</span><span class="o">=</span><span class="n">lib_section</span>
    <span class="p">)</span>

    <span class="c1"># Get the unique set of files referenced by the subcircuits in the Spice library.</span>
    <span class="n">lib_files</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span><span class="nb">str</span><span class="p">(</span><span class="n">spice_lib</span><span class="p">[</span><span class="n">subcirc</span><span class="p">])</span> <span class="k">for</span> <span class="n">subcirc</span> <span class="ow">in</span> <span class="n">spice_lib</span><span class="o">.</span><span class="n">subcircuits</span><span class="p">])</span>

    <span class="c1"># Go through the files and create a SKiDL Part for each subcircuit.</span>
    <span class="k">for</span> <span class="n">lib_file</span> <span class="ow">in</span> <span class="n">lib_files</span><span class="p">:</span>

        <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">lib_file</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
            <span class="c1"># Read the definition of each part line-by-line and then create</span>
            <span class="c1"># a Part object that gets stored in the part list.</span>
            <span class="k">for</span> <span class="n">statement</span> <span class="ow">in</span> <span class="n">_gather_statement</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>

                <span class="c1"># Look for the start of a part definition.</span>
                <span class="k">if</span> <span class="n">statement</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;.subckt&quot;</span><span class="p">:</span>

                    <span class="c1"># Create an un-filled part template.</span>
                    <span class="n">part</span> <span class="o">=</span> <span class="n">Part</span><span class="p">(</span><span class="n">part_defn</span><span class="o">=</span><span class="s2">&quot;don&#39;t care&quot;</span><span class="p">,</span> <span class="n">tool</span><span class="o">=</span><span class="n">SPICE</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="n">LIBRARY</span><span class="p">)</span>
                    <span class="n">part</span><span class="o">.</span><span class="n">fplist</span> <span class="o">=</span> <span class="p">[]</span>
                    <span class="n">part</span><span class="o">.</span><span class="n">aliases</span> <span class="o">=</span> <span class="p">[]</span>
                    <span class="n">part</span><span class="o">.</span><span class="n">num_units</span> <span class="o">=</span> <span class="mi">1</span>
                    <span class="n">part</span><span class="o">.</span><span class="n">ref_prefix</span> <span class="o">=</span> <span class="s2">&quot;X&quot;</span>
                    <span class="n">part</span><span class="o">.</span><span class="n">_ref</span> <span class="o">=</span> <span class="kc">None</span>
                    <span class="n">part</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
                    <span class="n">part</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
                    <span class="n">part</span><span class="o">.</span><span class="n">pins</span> <span class="o">=</span> <span class="p">[]</span>
                    <span class="n">part</span><span class="o">.</span><span class="n">pyspice</span> <span class="o">=</span> <span class="p">{</span>
                        <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;X&quot;</span><span class="p">,</span>
                        <span class="s2">&quot;add&quot;</span><span class="p">:</span> <span class="n">add_subcircuit_to_circuit</span><span class="p">,</span>
                        <span class="s2">&quot;lib&quot;</span><span class="p">:</span> <span class="n">spice_lib</span><span class="p">,</span>
                        <span class="s2">&quot;lib_path&quot;</span><span class="p">:</span> <span class="n">spice_lib_path</span><span class="p">,</span>
                        <span class="s2">&quot;lib_section&quot;</span><span class="p">:</span> <span class="n">lib_section</span><span class="p">,</span>
                    <span class="p">}</span>

                    <span class="c1"># Flesh-out the part.</span>
                    <span class="c1"># Parse the part definition.</span>
                    <span class="n">pieces</span> <span class="o">=</span> <span class="n">statement</span>
                    <span class="k">try</span><span class="p">:</span>
                        <span class="c1"># part defn: .subckt part_name pin1, pin2, ... pinN.</span>
                        <span class="n">part</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">pieces</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
                        <span class="n">part</span><span class="o">.</span><span class="n">pins</span> <span class="o">=</span> <span class="p">[</span><span class="n">Pin</span><span class="p">(</span><span class="n">num</span><span class="o">=</span><span class="n">p</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">p</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">pieces</span><span class="p">[</span><span class="mi">2</span><span class="p">:]]</span>
                        <span class="n">part</span><span class="o">.</span><span class="n">associate_pins</span><span class="p">()</span>
                    <span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
                        <span class="n">active_logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
                            <span class="s2">&quot;Misformatted SPICE subcircuit: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">part</span><span class="o">.</span><span class="n">part_defn</span><span class="p">)</span>
                        <span class="p">)</span>
                    <span class="k">else</span><span class="p">:</span>
                        <span class="c1"># Now find a symbol file for the part to assign names to the pins.</span>
                        <span class="c1"># First, check for LTSpice symbol file.</span>
                        <span class="n">sym_file</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">find_and_read_file</span><span class="p">(</span>
                            <span class="n">part</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
                            <span class="n">lib_search_paths_</span><span class="p">,</span>
                            <span class="s2">&quot;.asy&quot;</span><span class="p">,</span>
                            <span class="n">allow_failure</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
                            <span class="n">exclude_binary</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
                            <span class="n">descend</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span>
                        <span class="p">)</span>
                        <span class="k">if</span> <span class="n">sym_file</span><span class="p">:</span>
                            <span class="n">pin_names</span> <span class="o">=</span> <span class="p">[]</span>
                            <span class="n">pin_indices</span> <span class="o">=</span> <span class="p">[]</span>
                            <span class="k">for</span> <span class="n">sym_line</span> <span class="ow">in</span> <span class="n">sym_file</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">):</span>
                                <span class="k">if</span> <span class="ow">not</span> <span class="n">sym_line</span><span class="p">:</span>
                                    <span class="k">continue</span>
                                <span class="k">if</span> <span class="n">sym_line</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;pinattr pinname&quot;</span><span class="p">):</span>
                                    <span class="n">pin_names</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">sym_line</span><span class="o">.</span><span class="n">split</span><span class="p">()[</span><span class="mi">2</span><span class="p">])</span>
                                <span class="k">elif</span> <span class="n">sym_line</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;pinattr spiceorder&quot;</span><span class="p">):</span>
                                    <span class="n">pin_indices</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">sym_line</span><span class="o">.</span><span class="n">split</span><span class="p">()[</span><span class="mi">2</span><span class="p">])</span>
                                <span class="k">elif</span> <span class="n">sym_line</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;symattr description&quot;</span><span class="p">):</span>
                                    <span class="n">part</span><span class="o">.</span><span class="n">description</span> <span class="o">=</span> <span class="s2">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sym_line</span><span class="o">.</span><span class="n">split</span><span class="p">()[</span><span class="mi">2</span><span class="p">:])</span>

                            <span class="c1"># Pin names and indices should be matched by the order they</span>
                            <span class="c1"># appeared in the symbol file. Each index should match the</span>
                            <span class="c1"># order of the pins in the .subckt file.</span>
                            <span class="k">for</span> <span class="n">index</span><span class="p">,</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">pin_indices</span><span class="p">,</span> <span class="n">pin_names</span><span class="p">):</span>
                                <span class="n">part</span><span class="o">.</span><span class="n">pins</span><span class="p">[</span><span class="nb">int</span><span class="p">(</span><span class="n">index</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
                        <span class="k">else</span><span class="p">:</span>
                            <span class="c1"># No LTSpice symbol file, so check for PSPICE symbol file.</span>
                            <span class="n">sym_file</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">find_and_read_file</span><span class="p">(</span>
                                <span class="n">filename</span><span class="p">,</span>
                                <span class="n">lib_search_paths_</span><span class="p">,</span>
                                <span class="s2">&quot;.slb&quot;</span><span class="p">,</span>
                                <span class="n">allow_failure</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
                                <span class="n">exclude_binary</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
                                <span class="n">descend</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span>
                            <span class="p">)</span>
                            <span class="k">if</span> <span class="n">sym_file</span><span class="p">:</span>
                                <span class="n">pin_names</span> <span class="o">=</span> <span class="p">[]</span>
                                <span class="n">active</span> <span class="o">=</span> <span class="kc">False</span>
                                <span class="k">for</span> <span class="n">sym_line</span> <span class="ow">in</span> <span class="n">sym_file</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">):</span>
                                    <span class="n">sym_line</span> <span class="o">=</span> <span class="n">sym_line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
                                    <span class="k">if</span> <span class="ow">not</span> <span class="n">sym_line</span><span class="p">:</span>
                                        <span class="k">continue</span>
                                    <span class="n">line_parts</span> <span class="o">=</span> <span class="n">sym_line</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>
                                    <span class="k">if</span> <span class="n">line_parts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;*symbol&quot;</span><span class="p">:</span>
                                        <span class="n">active</span> <span class="o">=</span> <span class="n">line_parts</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">part</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
                                    <span class="k">if</span> <span class="n">active</span><span class="p">:</span>
                                        <span class="k">if</span> <span class="n">line_parts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;p&quot;</span><span class="p">:</span>
                                            <span class="n">pin_names</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">line_parts</span><span class="p">[</span><span class="mi">6</span><span class="p">])</span>
                                        <span class="k">elif</span> <span class="n">line_parts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;d&quot;</span><span class="p">:</span>
                                            <span class="n">part</span><span class="o">.</span><span class="n">description</span> <span class="o">=</span> <span class="s2">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">line_parts</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>

                                <span class="n">pin_indices</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">pin_names</span><span class="p">)))</span>
                                <span class="k">for</span> <span class="n">pin</span><span class="p">,</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">part</span><span class="o">.</span><span class="n">pins</span><span class="p">,</span> <span class="n">pin_names</span><span class="p">):</span>
                                    <span class="n">pin</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>

                    <span class="c1"># Add subcircuit part to the library.</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">add_parts</span><span class="p">(</span><span class="n">part</span><span class="p">)</span></div>



<div class="viewcode-block" id="parse_lib_part">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.parse_lib_part">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">parse_lib_part</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">partial_parse</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>  <span class="c1"># pylint: disable=unused-argument</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Create a Part using a part definition from a SPICE library.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="c1"># Parts in a SPICE library are already parsed and ready for use,</span>
    <span class="c1"># so just return the part.</span>
    <span class="k">return</span> <span class="bp">self</span></div>



<span class="c1"># Classes for device and xspice models.</span>


<div class="viewcode-block" id="XspiceModel">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.XspiceModel">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">class</span> <span class="nc">XspiceModel</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Object to hold the parameters for an XSPICE model.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>  <span class="c1"># The name to reference the model by.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">kwargs</span> <span class="o">=</span> <span class="n">kwargs</span></div>



<span class="c1"># DeviceModel and XspiceModel are the same.</span>
<span class="c1"># WARNING: DeviceModel overlaps a class in PySpice!</span>
<span class="n">DeviceModel</span> <span class="o">=</span> <span class="n">XspiceModel</span>


<div class="viewcode-block" id="gen_netlist">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.gen_netlist">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">gen_netlist</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Return a PySpice Circuit generated from a SKiDL circuit.</span>

<span class="sd">    Args:</span>
<span class="sd">        title: String containing the title for the PySpice circuit.</span>
<span class="sd">        libs: String or list of strings containing the paths to directories</span>
<span class="sd">            containing SPICE models.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="kn">from</span> <span class="nn">skidl</span> <span class="kn">import</span> <span class="n">lib_search_paths</span><span class="p">,</span> <span class="n">SPICE</span>

    <span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="o">.</span><span class="n">major</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
        <span class="n">active_logger</span><span class="o">.</span><span class="n">raise_</span><span class="p">(</span>
            <span class="ne">NotImplementedError</span><span class="p">,</span>
            <span class="s2">&quot;PySpice does not support Python 2, so a SPICE netlist cannot be generated.&quot;</span><span class="p">,</span>
        <span class="p">)</span>

    <span class="c1"># Create an empty PySpice circuit.</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;title&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>  <span class="c1"># Get title and remove it from kwargs.</span>
    <span class="n">circuit</span> <span class="o">=</span> <span class="n">PySpiceCircuit</span><span class="p">(</span><span class="n">title</span><span class="p">)</span>

    <span class="c1"># Default SPICE libraries will be read-in down below if needed.</span>
    <span class="n">default_libs</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="c1"># Initialize set of libraries to include in the PySpice circuit.</span>
    <span class="n">model_paths</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>  <span class="c1"># Paths to the model files that have been used.</span>
    <span class="n">lib_paths</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>  <span class="c1"># Paths to the library files that have been used.</span>
    <span class="n">lib_ids</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>  <span class="c1"># A lib_id is a tuple of the path to the lib file and a section.</span>

    <span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">parts</span><span class="p">:</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">pyspice</span> <span class="o">=</span> <span class="n">part</span><span class="o">.</span><span class="n">pyspice</span>
        <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
            <span class="k">continue</span>

        <span class="n">model</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">part</span><span class="p">,</span> <span class="s2">&quot;model&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">model</span><span class="p">:</span>
            <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="p">(</span><span class="n">XspiceModel</span><span class="p">,</span> <span class="n">DeviceModel</span><span class="p">)):</span>
                <span class="n">circuit</span><span class="o">.</span><span class="n">model</span><span class="p">(</span><span class="o">*</span><span class="n">model</span><span class="o">.</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">model</span><span class="o">.</span><span class="n">kwargs</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="n">path</span> <span class="o">=</span> <span class="n">pyspice</span><span class="p">[</span><span class="s2">&quot;lib&quot;</span><span class="p">][</span><span class="n">model</span><span class="p">]</span>
                <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
                    <span class="c1"># The part doesn&#39;t contain the library with the model, so look elsewhere.</span>
                    <span class="k">if</span> <span class="ow">not</span> <span class="n">default_libs</span><span class="p">:</span>
                        <span class="c1"># Read the default SPICE libraries.</span>
                        <span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="n">lib_search_paths</span><span class="p">[</span><span class="n">SPICE</span><span class="p">]:</span>
                            <span class="n">default_libs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
                                <span class="n">SpiceLibrary</span><span class="p">(</span><span class="n">root_path</span><span class="o">=</span><span class="n">path</span><span class="p">,</span> <span class="n">recurse</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
                            <span class="p">)</span>

                    <span class="c1"># Search for the model in the default libraries.</span>
                    <span class="n">path</span> <span class="o">=</span> <span class="kc">None</span>
                    <span class="k">for</span> <span class="n">lib</span> <span class="ow">in</span> <span class="n">default_libs</span><span class="p">:</span>
                        <span class="k">try</span><span class="p">:</span>
                            <span class="n">path</span> <span class="o">=</span> <span class="n">lib</span><span class="p">[</span><span class="n">model</span><span class="p">]</span>
                            <span class="k">break</span>
                        <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
                            <span class="k">pass</span>
                    <span class="k">if</span> <span class="n">path</span> <span class="o">==</span> <span class="kc">None</span><span class="p">:</span>
                        <span class="n">active_logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
                            <span class="s2">&quot;Unable to find model </span><span class="si">{}</span><span class="s2"> for part </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
                                <span class="n">model</span><span class="p">,</span> <span class="n">part</span><span class="o">.</span><span class="n">ref</span>
                            <span class="p">)</span>
                        <span class="p">)</span>

                <span class="c1"># Include the model file if it hasn&#39;t been included yet.</span>
                <span class="k">if</span> <span class="n">path</span> <span class="o">!=</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">path</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">model_paths</span><span class="p">:</span>
                    <span class="n">circuit</span><span class="o">.</span><span class="n">include</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
                    <span class="n">model_paths</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>

        <span class="k">try</span><span class="p">:</span>
            <span class="n">path</span><span class="p">,</span> <span class="n">section</span> <span class="o">=</span> <span class="n">pyspice</span><span class="p">[</span><span class="s2">&quot;lib_path&quot;</span><span class="p">],</span> <span class="n">pyspice</span><span class="p">[</span><span class="s2">&quot;lib_section&quot;</span><span class="p">]</span>
        <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
            <span class="k">continue</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">section</span><span class="p">:</span>
            <span class="c1"># Libraries without a section are added as include files.</span>
            <span class="k">if</span> <span class="n">path</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">lib_paths</span><span class="p">:</span>
                <span class="n">circuit</span><span class="o">.</span><span class="n">include</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
                <span class="n">lib_paths</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">lib_id</span> <span class="o">=</span> <span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">section</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">lib_id</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">lib_ids</span><span class="p">:</span>
                <span class="n">circuit</span><span class="o">.</span><span class="n">lib</span><span class="p">(</span><span class="o">*</span><span class="n">lib_id</span><span class="p">)</span>
                <span class="n">lib_ids</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">lib_id</span><span class="p">)</span>

    <span class="c1"># Add each part in the SKiDL circuit to the PySpice circuit.</span>
    <span class="c1"># TODO: Make sure self.parts is processed in order that parts were created so ngspice doesn&#39;t get references to parts before they exist.</span>
    <span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">parts</span><span class="p">:</span>
        <span class="c1"># Add each part using its add function which will be either</span>
        <span class="c1"># add_part_to_circuit() or add_subcircuit_to_circuit().</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">add_func</span> <span class="o">=</span> <span class="n">part</span><span class="o">.</span><span class="n">pyspice</span><span class="p">[</span><span class="s2">&quot;add&quot;</span><span class="p">]</span>
        <span class="k">except</span> <span class="p">(</span><span class="ne">AttributeError</span><span class="p">,</span> <span class="ne">KeyError</span><span class="p">):</span>
            <span class="n">active_logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Part has no SPICE model: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">part</span><span class="p">))</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">add_func</span><span class="p">(</span><span class="n">part</span><span class="p">,</span> <span class="n">circuit</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">circuit</span></div>



<div class="viewcode-block" id="node">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.node">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">node</span><span class="p">(</span><span class="n">net_pin_part</span><span class="p">):</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">net_pin_part</span><span class="p">,</span> <span class="n">Net</span><span class="p">):</span>
        <span class="c1"># Replace any special chars in a net name because Spice doesn&#39;t like them.</span>
        <span class="k">return</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;\W&quot;</span><span class="p">,</span> <span class="s2">&quot;_&quot;</span><span class="p">,</span> <span class="n">net_pin_part</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">net_pin_part</span><span class="p">,</span> <span class="n">Pin</span><span class="p">):</span>
        <span class="c1"># Replace any special chars in a net name because Spice doesn&#39;t like them.</span>
        <span class="k">return</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;\W&quot;</span><span class="p">,</span> <span class="s2">&quot;_&quot;</span><span class="p">,</span> <span class="n">net_pin_part</span><span class="o">.</span><span class="n">net</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">net_pin_part</span><span class="p">,</span> <span class="n">Part</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">net_pin_part</span><span class="o">.</span><span class="n">ref</span></div>



<span class="k">def</span> <span class="nf">_xspice_node</span><span class="p">(</span><span class="n">net_or_pin</span><span class="p">):</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">net_or_pin</span><span class="p">,</span> <span class="n">Net</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">net_or_pin</span><span class="o">.</span><span class="n">name</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">net_or_pin</span><span class="p">,</span> <span class="n">Pin</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">net_or_pin</span><span class="o">.</span><span class="n">is_connected</span><span class="p">():</span>
            <span class="k">return</span> <span class="n">net_or_pin</span><span class="o">.</span><span class="n">net</span><span class="o">.</span><span class="n">name</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># For XSPICE parts, unconnected pins are connected to NULL node.</span>
            <span class="k">return</span> <span class="s2">&quot;NULL&quot;</span>


<span class="k">def</span> <span class="nf">_get_spice_ref</span><span class="p">(</span><span class="n">part</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Return a SPICE reference ID for the part.&quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">part</span><span class="o">.</span><span class="n">ref</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">part</span><span class="o">.</span><span class="n">ref_prefix</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">part</span><span class="o">.</span><span class="n">ref</span><span class="p">[</span><span class="nb">len</span><span class="p">(</span><span class="n">part</span><span class="o">.</span><span class="n">ref_prefix</span><span class="p">)</span> <span class="p">:]</span>
    <span class="k">return</span> <span class="n">part</span><span class="o">.</span><span class="n">ref</span>


<span class="k">def</span> <span class="nf">_get_kwargs</span><span class="p">(</span><span class="n">part</span><span class="p">,</span> <span class="n">kw</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Return a dict of keyword arguments to PySpice element constructor.&quot;&quot;&quot;</span>
    <span class="n">kwargs</span> <span class="o">=</span> <span class="p">{}</span>

    <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">param_name</span> <span class="ow">in</span> <span class="n">kw</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="c1"># The key indicates some attribute of the part.</span>
            <span class="n">part_attr</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">part</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
        <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
            <span class="k">pass</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># If the keyword argument is a Part, then substitute the part</span>
            <span class="c1"># reference because it&#39;s probably a control current for something</span>
            <span class="c1"># like a current-controlled source or switch.</span>
            <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">part_attr</span><span class="p">,</span> <span class="n">Part</span><span class="p">):</span>
                <span class="n">kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="n">param_name</span><span class="p">:</span> <span class="n">part_attr</span><span class="o">.</span><span class="n">ref</span><span class="p">})</span>
            <span class="c1"># If the keyword argument is a Net, substitute the net name.</span>
            <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">part_attr</span><span class="p">,</span> <span class="n">Net</span><span class="p">):</span>
                <span class="n">kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="n">param_name</span><span class="p">:</span> <span class="n">node</span><span class="p">(</span><span class="n">part_attr</span><span class="p">)})</span>
            <span class="c1"># If the keyword argument is a Pin, skip it. It gets handled below.</span>
            <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">part_attr</span><span class="p">,</span> <span class="n">Pin</span><span class="p">):</span>
                <span class="k">continue</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="n">param_name</span><span class="p">:</span> <span class="n">part_attr</span><span class="p">})</span>

    <span class="k">for</span> <span class="n">pin</span> <span class="ow">in</span> <span class="n">part</span><span class="o">.</span><span class="n">pins</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">pin</span><span class="o">.</span><span class="n">is_connected</span><span class="p">():</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="n">param_name</span> <span class="o">=</span> <span class="n">kw</span><span class="p">[</span><span class="n">pin</span><span class="o">.</span><span class="n">name</span><span class="p">]</span>
                <span class="n">kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="n">param_name</span><span class="p">:</span> <span class="n">node</span><span class="p">(</span><span class="n">pin</span><span class="p">)})</span>
            <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
                <span class="n">active_logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
                    <span class="s2">&quot;Part </span><span class="si">{}</span><span class="s2">-</span><span class="si">{}</span><span class="s2"> has no </span><span class="si">{}</span><span class="s2"> pin: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
                        <span class="n">part</span><span class="o">.</span><span class="n">ref</span><span class="p">,</span> <span class="n">part</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">pin</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">part</span>
                    <span class="p">)</span>
                <span class="p">)</span>

    <span class="k">return</span> <span class="n">kwargs</span>


<div class="viewcode-block" id="not_implemented">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.not_implemented">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">not_implemented</span><span class="p">(</span><span class="n">part</span><span class="p">,</span> <span class="n">circuit</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Unable to add a particular SPICE part to a circuit.&quot;&quot;&quot;</span>
    <span class="n">active_logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
        <span class="s2">&quot;Function not implemented for </span><span class="si">{}</span><span class="s2"> - </span><span class="si">{}</span><span class="s2">.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">part</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">part</span><span class="o">.</span><span class="n">ref</span><span class="p">)</span>
    <span class="p">)</span></div>



<div class="viewcode-block" id="add_part_to_circuit">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.add_part_to_circuit">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">add_part_to_circuit</span><span class="p">(</span><span class="n">part</span><span class="p">,</span> <span class="n">circuit</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Add a part to a PySpice Circuit object.</span>

<span class="sd">    Args:</span>
<span class="sd">        part: SKiDL Part object.</span>
<span class="sd">        circuit: PySpice Circuit object.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="c1"># The device reference is always the first positional argument.</span>
    <span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">_get_spice_ref</span><span class="p">(</span><span class="n">part</span><span class="p">)]</span>

    <span class="c1"># Get keyword arguments.</span>
    <span class="n">kwargs</span> <span class="o">=</span> <span class="n">_get_kwargs</span><span class="p">(</span><span class="n">part</span><span class="p">,</span> <span class="n">part</span><span class="o">.</span><span class="n">pyspice</span><span class="p">[</span><span class="s2">&quot;kw&quot;</span><span class="p">])</span>

    <span class="c1"># Convert model argument if it exists and it&#39;s not a string.</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;model&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">part</span><span class="o">.</span><span class="n">model</span><span class="o">.</span><span class="n">name</span>
    <span class="k">except</span> <span class="p">(</span><span class="ne">KeyError</span><span class="p">,</span> <span class="ne">AttributeError</span><span class="p">):</span>
        <span class="c1"># Don&#39;t change model kw param if it doesn&#39;t exist or is a string.</span>
        <span class="k">pass</span>

    <span class="c1"># Add the part to the PySpice circuit.</span>
    <span class="nb">getattr</span><span class="p">(</span><span class="n">circuit</span><span class="p">,</span> <span class="n">part</span><span class="o">.</span><span class="n">pyspice</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">])(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>



<span class="k">def</span> <span class="nf">_get_net_names</span><span class="p">(</span><span class="n">part</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Return a list of net names attached to the pins of a part.&quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="p">[</span><span class="n">node</span><span class="p">(</span><span class="n">pin</span><span class="p">)</span> <span class="k">for</span> <span class="n">pin</span> <span class="ow">in</span> <span class="n">part</span><span class="o">.</span><span class="n">pins</span> <span class="k">if</span> <span class="n">pin</span><span class="o">.</span><span class="n">is_connected</span><span class="p">()]</span>


<div class="viewcode-block" id="Parameters">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.Parameters">[docs]</a>
<span class="k">class</span> <span class="nc">Parameters</span><span class="p">(</span><span class="nb">dict</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Class for holding Spice subcircuit parameters.&quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">params</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__copy__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">copy</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">}</span></div>



<div class="viewcode-block" id="add_subcircuit_to_circuit">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.add_subcircuit_to_circuit">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">add_subcircuit_to_circuit</span><span class="p">(</span><span class="n">part</span><span class="p">,</span> <span class="n">circuit</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Add a .SUBCKT part to a PySpice Circuit object.</span>

<span class="sd">    Args:</span>
<span class="sd">        part: SKiDL Part object.</span>
<span class="sd">        circuit: PySpice Circuit object.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="c1"># The device reference is always the first positional argument.</span>
    <span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">_get_spice_ref</span><span class="p">(</span><span class="n">part</span><span class="p">)]</span>

    <span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">part</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
    <span class="n">args</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">_get_net_names</span><span class="p">(</span><span class="n">part</span><span class="p">))</span>

    <span class="c1"># Add the part to the PySpice circuit.</span>
    <span class="kn">from</span> <span class="nn">skidl.pyspice</span> <span class="kn">import</span> <span class="n">Parameters</span>

    <span class="n">params</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">part</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">Parameters</span><span class="p">):</span>
            <span class="n">params</span> <span class="o">=</span> <span class="n">v</span>
    <span class="nb">getattr</span><span class="p">(</span><span class="n">circuit</span><span class="p">,</span> <span class="n">part</span><span class="o">.</span><span class="n">pyspice</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">])(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">)</span></div>



<div class="viewcode-block" id="add_xspice_to_circuit">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.add_xspice_to_circuit">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">add_xspice_to_circuit</span><span class="p">(</span><span class="n">part</span><span class="p">,</span> <span class="n">circuit</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Add an XSPICE part to a PySpice Circuit object.</span>

<span class="sd">    Args:</span>
<span class="sd">        part: SKiDL Part object.</span>
<span class="sd">        circuit: PySpice Circuit object.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="c1"># The device reference is always the first positional argument.</span>
    <span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">_get_spice_ref</span><span class="p">(</span><span class="n">part</span><span class="p">)]</span>

    <span class="c1"># Add the pins to the argument list.</span>
    <span class="k">for</span> <span class="n">pin</span> <span class="ow">in</span> <span class="n">part</span><span class="o">.</span><span class="n">pins</span><span class="p">:</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">pin</span><span class="p">,</span> <span class="n">Pin</span><span class="p">):</span>
            <span class="c1"># Add a non-vector pin. Use _xspice_node() in case pin is unconnected.</span>
            <span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_xspice_node</span><span class="p">(</span><span class="n">pin</span><span class="p">))</span>
        <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">pin</span><span class="p">,</span> <span class="n">XspicePinList</span><span class="p">):</span>
            <span class="c1"># Add pins from a pin vector.</span>
            <span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;[&quot;</span> <span class="o">+</span> <span class="s2">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">node</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">pin</span><span class="p">])</span> <span class="o">+</span> <span class="s2">&quot;]&quot;</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">active_logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Illegal XSPICE argument: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">pin</span><span class="p">))</span>

    <span class="c1"># The XSPICE model name should be the only keyword argument.</span>
    <span class="n">kwargs</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;model&quot;</span><span class="p">:</span> <span class="n">part</span><span class="o">.</span><span class="n">model</span><span class="o">.</span><span class="n">name</span><span class="p">}</span>

    <span class="c1"># Add the part to the PySpice circuit.</span>
    <span class="nb">getattr</span><span class="p">(</span><span class="n">circuit</span><span class="p">,</span> <span class="n">part</span><span class="o">.</span><span class="n">pyspice</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">])(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>



<div class="viewcode-block" id="add_xspice_io">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.add_xspice_io">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">add_xspice_io</span><span class="p">(</span><span class="n">part</span><span class="p">,</span> <span class="n">io</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Add XSPICE I/O to the pins of a part.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">io</span><span class="p">:</span>
        <span class="k">return</span>

    <span class="c1"># Change a string into a list with a single string element.</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">io</span><span class="p">,</span> <span class="n">basestring</span><span class="p">):</span>
        <span class="n">io</span> <span class="o">=</span> <span class="p">[</span><span class="n">io</span><span class="p">]</span>

    <span class="c1"># Join all the pin name arguments into a comma-separated string and then split them into a list.</span>
    <span class="n">ios</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">INDEX_SEPARATOR</span><span class="p">,</span> <span class="s2">&quot;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">io</span><span class="p">))</span>

    <span class="c1"># Add a pin to the part for each pin name.</span>
    <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">arg</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">ios</span><span class="p">):</span>
        <span class="n">arg</span> <span class="o">=</span> <span class="n">arg</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>  <span class="c1"># Strip any spaces that may have been between pin names.</span>

        <span class="c1"># If [pin_name] or pin_name[], then add a PinList to the part. Don&#39;t use</span>
        <span class="c1"># part.add_pins() because it will flatten the PinList and add nothing since</span>
        <span class="c1"># the PinList is empty.</span>
        <span class="k">if</span> <span class="n">arg</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">arg</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;[]&quot;</span><span class="p">:</span>
            <span class="n">part</span><span class="o">.</span><span class="n">pins</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">XspicePinList</span><span class="p">(</span><span class="n">num</span><span class="o">=</span><span class="n">i</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">arg</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">part</span><span class="o">=</span><span class="n">part</span><span class="p">))</span>
        <span class="k">elif</span> <span class="n">arg</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">:]</span> <span class="o">==</span> <span class="s2">&quot;[]&quot;</span><span class="p">:</span>
            <span class="n">part</span><span class="o">.</span><span class="n">pins</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">XspicePinList</span><span class="p">(</span><span class="n">num</span><span class="o">=</span><span class="n">i</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">arg</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="o">-</span><span class="mi">2</span><span class="p">],</span> <span class="n">part</span><span class="o">=</span><span class="n">part</span><span class="p">))</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># Add a simple, non-vector pin.</span>
            <span class="n">part</span><span class="o">.</span><span class="n">add_pins</span><span class="p">(</span><span class="n">Pin</span><span class="p">(</span><span class="n">num</span><span class="o">=</span><span class="n">i</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">arg</span><span class="p">))</span></div>



<div class="viewcode-block" id="convert_for_spice">
<a class="viewcode-back" href="../../../../rst_output/skidl.tools.spice.spice.html#skidl.tools.spice.spice.convert_for_spice">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">convert_for_spice</span><span class="p">(</span><span class="n">part</span><span class="p">,</span> <span class="n">spice_part</span><span class="p">,</span> <span class="n">pin_map</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Convert a Part object for use with SPICE.</span>

<span class="sd">    Args:</span>
<span class="sd">        part: SKiDL Part object that will be converted for use as a SPICE component.</span>
<span class="sd">        spice_part (Part): The type of SPICE Part to be converted to.</span>
<span class="sd">        pin_map (dict): Dict with pin numbers/names of part as keys and num/names of spice_part pins as replacement values.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="c1"># Give the part access to the PySpice information from the SPICE part.</span>
    <span class="n">part</span><span class="o">.</span><span class="n">pyspice</span> <span class="o">=</span> <span class="n">spice_part</span><span class="o">.</span><span class="n">pyspice</span>

    <span class="c1"># Give the part the additional aliases from the SPICE part.</span>
    <span class="n">part</span><span class="o">.</span><span class="n">aliases</span> <span class="o">+=</span> <span class="n">spice_part</span><span class="o">.</span><span class="n">aliases</span>

    <span class="c1"># Look-up pin names/numbers to create a mapping between actual Pin objects.</span>
    <span class="n">pin_map</span> <span class="o">=</span> <span class="p">[[</span><span class="n">part</span><span class="p">[</span><span class="n">dst</span><span class="p">],</span> <span class="n">spice_part</span><span class="p">[</span><span class="n">src</span><span class="p">]]</span> <span class="k">for</span> <span class="n">dst</span><span class="p">,</span> <span class="n">src</span> <span class="ow">in</span> <span class="n">pin_map</span><span class="o">.</span><span class="n">items</span><span class="p">()]</span>

    <span class="c1"># Pull some info from the SPICE part pins into the part pins.</span>
    <span class="k">for</span> <span class="n">dst_pin</span><span class="p">,</span> <span class="n">src_pin</span> <span class="ow">in</span> <span class="n">pin_map</span><span class="p">:</span>
        <span class="n">dst_pin</span><span class="o">.</span><span class="n">num</span> <span class="o">=</span> <span class="n">src_pin</span><span class="o">.</span><span class="n">num</span>
        <span class="n">dst_pin</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">src_pin</span><span class="o">.</span><span class="n">name</span>
        <span class="n">dst_pin</span><span class="o">.</span><span class="n">aliases</span> <span class="o">+=</span> <span class="n">src_pin</span><span class="o">.</span><span class="n">aliases</span></div>



<span class="k">class</span> <span class="nc">XspicePinList</span><span class="p">(</span><span class="nb">list</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A list of Pin objects that&#39;s meant to look something like a Pin to a Part.</span>
<span class="sd">    This is used for vector I/O of XSPICE parts.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">num</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">part</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
        <span class="c1"># The list needs the following attributes to behave like a Pin.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">aliases</span> <span class="o">=</span> <span class="n">Alias</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">num</span> <span class="o">=</span> <span class="n">num</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">part</span> <span class="o">=</span> <span class="n">part</span>

    <span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">i</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Get a Pin from the list. Add Pin objects to the list if they don&#39;t exist.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">l</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__len__</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">i</span> <span class="o">&gt;=</span> <span class="n">l</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span><span class="n">Pin</span><span class="p">(</span><span class="n">num</span><span class="o">=</span><span class="n">j</span><span class="p">,</span> <span class="n">part</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">part</span><span class="p">)</span> <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">l</span><span class="p">,</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)])</span>
        <span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__getitem__</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">if</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__len__</span><span class="p">()</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="n">tmp</span> <span class="o">=</span> <span class="p">[</span><span class="n">Pin</span><span class="p">()]</span>
            <span class="k">return</span> <span class="p">(</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">tmp</span><span class="p">)</span>
        <span class="k">return</span> <span class="p">(</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__iter__</span><span class="p">())</span>  <span class="c1"># Return generator expr.</span>

    <span class="k">def</span> <span class="fm">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">l</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__len__</span><span class="p">()</span>
        <span class="k">return</span> <span class="n">l</span> <span class="ow">or</span> <span class="mi">1</span>

    <span class="k">def</span> <span class="nf">copy</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">attribs</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a copy of a PinList for use when a Part is copied.</span>

<span class="sd">        Args:</span>
<span class="sd">            attribs(dict): Attributes to apply to copied part pins.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">cpy</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">num</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">part</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">pin</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span>
            <span class="n">cpy</span> <span class="o">+=</span> <span class="n">pin</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="o">**</span><span class="n">attribs</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">cpy</span>

    <span class="k">def</span> <span class="nf">disconnect</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Disconnect all the pins in the list.&quot;&quot;&quot;</span>
        <span class="k">for</span> <span class="n">pin</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span>
            <span class="n">pin</span><span class="o">.</span><span class="n">disconnect</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">is_connected</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">pin</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">pin</span><span class="o">.</span><span class="n">is_connected</span><span class="p">():</span>
                <span class="k">return</span> <span class="kc">True</span>
        <span class="k">return</span> <span class="kc">False</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span>

    <span class="nd">@name</span><span class="o">.</span><span class="n">setter</span>
    <span class="k">def</span> <span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nm</span><span class="p">):</span>
        <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>  <span class="c1"># Remove any pre-existing name.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">aliases</span> <span class="o">+=</span> <span class="n">nm</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="n">nm</span>

    <span class="nd">@name</span><span class="o">.</span><span class="n">deleter</span>
    <span class="k">def</span> <span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">aliases</span><span class="o">.</span><span class="n">discard</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
            <span class="k">pass</span>
</pre></div>

            <div class="clearer"></div>
          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
<search id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../../../../search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
      <input type="submit" value="Go" />
    </form>
    </div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../../../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="../../../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../../../index.html">SKiDL 1.2.2 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../../../index.html" >Module code</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">skidl.tools.spice.spice</a></li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
    &#169; Copyright 2016-2024, Dave Vandenbout.
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 7.3.7.
    </div>
  </body>
</html>